/********************************************************
*Implementacion de Lista                                *
*Author     :   Simon Emmanuel Gutierrez Brida          *
*Version    :   0.1                                     *
*Fecha      :   Septiembre/2011                         *
*------------------------------------------------------ *
*********************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lista.h"

Lista* nuevaLista() {
    Lista *nueva = (Lista*) malloc(sizeof(Lista));
    nueva->inicio = NULL;
    nueva->longitud = 0;
    return nueva;
}

Variable* obtener(Lista *lista, char *id) {
    Nodo *runner = lista->inicio;
    Variable *result = NULL;
    bool found = false;
    while ((runner != NULL) && (!found)) {
        if (strcmp(obtenerIdentificador(obtenerInfo(runner)), id) == 0) {
            found = true;
            result = obtenerInfo(runner);
        } else {
            runner = obtenerSiguiente(runner);
        }
    }
    return result;
}

Variable* obtener_indexado(Lista *lista, int index) {
    Nodo *runner = lista->inicio;
    Variable *result = NULL;
    bool validIndex = (index >= 0) && (index < longitud(lista));
    int i = 0;
    if ((runner != NULL) && (validIndex)) {
        while (i < index) {
            runner = obtenerSiguiente(runner);
            i++;
        }
        result = obtenerInfo(runner);
    }
    return result;
}

int longitud(Lista *lista) {
    return lista->longitud;
}

bool existe_var(Lista *lista, Variable *var) {
    return obtener(lista, var->id) != NULL;
}

bool existe_id(Lista *lista, char *id) {
    return obtener(lista, id) != NULL;
}

void agregar(Lista *lista, Variable *var) {
    Nodo *nuevo = nuevoNodo_info_siguiente(var, lista->inicio);
    lista->inicio = nuevo;
    lista->longitud = longitud(lista) + 1;
}

void eliminar(Lista *lista, char *id) {
    Nodo *runner = lista->inicio;
    if (lista->inicio != NULL) {
        if (strcmp(obtenerIdentificador(obtenerInfo(runner)),id) == 0) { /*el elemento a borrar es el primero*/
            lista->inicio = obtenerSiguiente(lista->inicio);
            free(runner);
            lista->longitud = longitud(lista) - 1;
        } else {
            bool found = false;
            Nodo *elim;
            while ((obtenerSiguiente(runner) != NULL) && (!found)) {
                if (strcmp(obtenerIdentificador(obtenerInfo(obtenerSiguiente(runner))), id) == 0) {
                    elim = obtenerSiguiente(runner);
                    definirSiguiente(runner,obtenerSiguiente(obtenerSiguiente(runner)));
                    found = true;
                } else {
                    runner = obtenerSiguiente(runner);
                }
            }
            if (found) {
                free(elim);
                lista->longitud = longitud(lista) - 1;
            }
        }
    }
}